/*
    Copyright (c);2019-2022;Wiscom System;

	All rights reserved.

    Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this
       list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright notice,
       this list of conditions and the following disclaimer in the documentation
       and/or other materials provided with the distribution.
    3. Neither the name of the Wiscom System nor the names of its contributors
       may be used to endorse or promote products derived from this software without
       specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/

#ifndef PCRAM_H
#define PCRAM_H

#include "csg.h"

#define GMC_BCR_1    0x0000
#define GMC_BCR_2    0x0008
#define GMC_BTR_1    0x0004
#define GMC_BTR_2    0x000C
#define GMC_BWTR_1   0x0024
#define GMC_BWTR_2   0x002C

/*BASE ADDR*/
#define GMC_SDRAM1_BASE                     (uint64_t)(GMC0_MEM_BASE)
#define GMC_SDRAM2_BASE                     ((uint64_t)(GMC0_MEM_BASE  + 0x10000000))
#define GMC_SRAM1_BASE                       ((uint64_t)(GMC0_MEM_BASE + 0x20000000))
#define GMC_SRAM2_BASE                       ((uint64_t)(GMC0_MEM_BASE + 0x24000000))
#define GMC_SRAM3_BASE                       ((uint64_t)(GMC0_MEM_BASE + 0x28000000))
#define GMC_SRAM4_BASE                       ((uint64_t)(GMC0_MEM_BASE + 0x2C000000))

/* ===== BCR===== */
#define GMC_BCR_MBKEN_OFS                    0U  /*!< N/A */
#define GMC_BCR_MBKEN_MASK                   BIT(0)
#define GMC_BCR_MBKEN(regval)                (BIT(0) & ((uint32_t)(regval) << 0))
#define GMC_MBKEN_ENABLE                      BIT(0)  /*!< ENABLE */
#define GMC_MBKEN_DISABLE                     0x0UL  /*!< DISABLE */
#define IS_GMC_MBKEN(regval)                  (                                           (regval) == GMC_MBKEN_ENABLE              ) ||                                            (regval) == GMC_MBKEN_DISABLE             ) ||                                    )
#define GMC_BCR_MUXEN_OFS                    1U  /*!< N/A */
#define GMC_BCR_MUXEN_MASK                    BIT(1)
#define GMC_BCR_MUXEN(regval)                (BIT(1) & ((uint32_t)(regval) << 1))
#define GMC_MUXEN_ENABLE                      BIT(1)  /*!< ENABLE */
#define GMC_MUXEN_DISABLE                     0x0UL  /*!< DISABLE */
#define IS_GMC_MUXEN(regval)                  (                                           (regval) == GMC_MUXEN_ENABLE              ) ||                                            (regval) == GMC_MUXEN_DISABLE             ) ||                                    )
#define GMC_BCR_MTYP_MASK                    BITS(2,3)
#define GMC_BCR_MTYP(regval)                 (BITS(2,3) & ((uint32_t)(regval) << 2))
#define GMC_MTYP_SRAM                         GMC_BCR_MTYP(0)  /*!< SRAM */
#define GMC_MTYP_PSRAM                        GMC_BCR_MTYP(1)  /*!< PSRAM */
#define GMC_MTYP_NOR                          GMC_BCR_MTYP(2)  /*!< NOR */
#define IS_GMC_MTYP(regval)                   (                                            (regval) == GMC_MTYP_SRAM                ) ||                                             (regval) == GMC_MTYP_PSRAM               ) ||                                             (regval) == GMC_MTYP_NOR                 ) ||                                    )
#define GMC_BCR_MWID_MASK                    BITS(4,5)
#define GMC_BCR_MWID(regval)                 (BITS(4,5) & ((uint32_t)(regval) << 4))
#define GMC_MWID_WIDTH_8                      GMC_BCR_MWID(0)  /*!< WIDTH_8 */
#define GMC_MWID_WIDTH_16                     GMC_BCR_MWID(1)  /*!< WIDTH_16 */
#define GMC_MWID_WIDTH_32                     GMC_BCR_MWID(2)  /*!< WIDTH_32 */
#define IS_GMC_MWID(regval)                   (                                            (regval) == GMC_MWID_WIDTH_8             ) ||                                             (regval) == GMC_MWID_WIDTH_16            ) ||                                             (regval) == GMC_MWID_WIDTH_32            ) ||                                    )
#define GMC_BCR_FACCEN_OFS                   6U  /*!< N/A */
#define GMC_BCR_FACCEN_MASK                  BIT(6)
#define GMC_BCR_FACCEN(regval)               (BIT(6) & ((uint32_t)(regval) << 6))
#define GMC_FACCEN_ENABLE                     BIT(6)  /*!< ENABLE */
#define GMC_FACCEN_DISABLE                    0x0UL  /*!< DISABLE */
#define IS_GMC_FACCEN(regval)                 (                                          (regval) == GMC_FACCEN_ENABLE              ) ||                                           (regval) == GMC_FACCEN_DISABLE             ) ||                                    )

#define GMC_BCR_MODEXMC_OFS                   7U  /*!< N/A */
#define GMC_BCR_MODEXMC_MASK                  BIT(7)
#define GMC_BCR_MODEXMC(regval)               (BIT(7) & ((uint32_t)(regval) << 7))
#define GMC_MODEXMC_ENABLE                     BIT(7)  /*!< ENABLE */
#define GMC_MODEXMC_DISABLE                    0x0UL  /*!< DISABLE */
#define IS_GMC_MODEXMC(regval)                 (                                          (regval) == GMC_MODEXMC_ENABLE              ) ||                                           (regval) == GMC_MODEXMC_DISABLE             ) ||                                    )

#define GMC_BCR_BURSTEN_OFS                  8U  /*!< N/A */
#define GMC_BCR_BURSTEN_MASK                 BIT(8)
#define GMC_BCR_BURSTEN(regval)              (BIT(8) & ((uint32_t)(regval) << 8))
#define GMC_BURSTEN_ENABLE                    BIT(8)  /*!< ENABLE */
#define GMC_BURSTEN_DISABLE                   0x0UL  /*!< DISABLE */
#define IS_GMC_BURSTEN(regval)                (                                         (regval) == GMC_BURSTEN_ENABLE              ) ||                                          (regval) == GMC_BURSTEN_DISABLE             ) ||                                    )
#define GMC_BCR_WAITPOL_OFS                  9U  /*!< N/A */
#define GMC_BCR_WAITPOL_MASK                 BIT(9)
#define GMC_BCR_WAITPOL(regval)              (BIT(9) & ((uint32_t)(regval) << 9))
#define GMC_WAITPOL_LOW                       0x0UL  /*!< LOW */
#define GMC_WAITPOL_HIGH                      BIT(9)  /*!< HIGH */
#define IS_GMC_WAITPOL(regval)                (                                         (regval) == GMC_WAITPOL_LOW                 ) ||                                          (regval) == GMC_WAITPOL_HIGH                ) ||                                    )
#define GMC_BCP_RESERVE_OFS                  10U
#define GMC_BCR_RESERVE_MASK                 BIT(10)
#define GMC_BCR_RESERVE(regval)              (BIT(10) & ((uint32_t)(regval) << 10))

#define GMC_BCR_WAITCFG_OFS                  11U  /*!< N/A */
#define GMC_BCR_WAITCFG_MASK                 BIT(11)
#define GMC_BCR_WAITCFG(regval)              (BIT(11) & ((uint32_t)(regval) << 11))
#define GMC_WAITCFG_BEFORE_WS                 0x0UL  /*!< BEFORE_WS */
#define GMC_WAITCFG_DURING_WS                 BIT(11)  /*!< DURING_WS */
#define IS_GMC_WAITCFG(regval)                (                                         (regval) == GMC_WAITCFG_BEFORE_WS           ) ||                                          (regval) == GMC_WAITCFG_DURING_WS           ) ||                                    )
#define GMC_BCR_WREN_OFS                     12U  /*!< N/A */
#define GMC_BCR_WREN_MASK                    BIT(12) 
#define GMC_BCR_WREN(regval)                 (BIT(12) & ((uint32_t)(regval) << 12))
#define GMC_WREN_ENABLE                       BIT(12)  /*!< ENABLE */
#define GMC_WREN_DISABLE                      0x0UL  /*!< DISABLE */
#define IS_GMC_WREN(regval)                   (                                            (regval) == GMC_WREN_ENABLE              ) ||                                             (regval) == GMC_WREN_DISABLE             ) ||                                    )
#define GMC_BCR_WAITEN_OFS                   13U  /*!< N/A */
#define GMC_BCR_WAITEN_MASK                  BIT(13)
#define GMC_BCR_WAITEN(regval)               (BIT(13) & ((uint32_t)(regval) << 13))
#define GMC_WAITEN_ENABLE                     BIT(13)  /*!< ENABLE */
#define GMC_WAITEN_DISABLE                    0x0UL  /*!< DISABLE */
#define IS_GMC_WAITEN(regval)                 (                                          (regval) == GMC_WAITEN_ENABLE              ) ||                                           (regval) == GMC_WAITEN_DISABLE             ) ||                                    )
#define GMC_BCR_EXTMOD_OFS                   14U  /*!< N/A */
#define GMC_BCR_EXTMOD_MASK                  BIT(14)
#define GMC_BCR_EXTMOD(regval)               (BIT(14) & ((uint32_t)(regval) << 14))
#define GMC_EXTMOD_ENABLE                     BIT(14)  /*!< ENABLE */
#define GMC_EXTMOD_DISABLE                    0x0UL  /*!< DISABLE */
#define IS_GMC_EXTMOD(regval)                 (                                          (regval) == GMC_EXTMOD_ENABLE              ) ||                                           (regval) == GMC_EXTMOD_DISABLE             ) ||                                    )
#define GMC_BCR_ASYNCWAIT_OFS                15U  /*!< N/A */
#define GMC_BCR_ASYNCWAIT_MASK               BIT(15)
#define GMC_BCR_ASYNCWAIT(regval)            (BIT(15) & ((uint32_t)(regval) << 15))
#define GMC_ASYNCWAIT_ENABLE                  BIT(15)  /*!< ENABLE */
#define GMC_ASYNCWAIT_DISABLE                 0x0UL  /*!< DISABLE */
#define IS_GMC_ASYNCWAIT(regval)              (                                       (regval) == GMC_ASYNCWAIT_ENABLE              ) ||                                        (regval) == GMC_ASYNCWAIT_DISABLE             ) ||                                    )
#define GMC_BCR_CPSIZE_MASK                  BITS(16,18)
#define GMC_BCR_CPSIZE(regval)               (BITS(16,18) & ((uint32_t)(regval) << 16))
#define GMC_CPSIZE_NONE                       GMC_BCR_CPSIZE(0)  /*!< NONE */
#define GMC_CPSIZE_128                        GMC_BCR_CPSIZE(1)  /*!< 128 */
#define GMC_CPSIZE_256                        GMC_BCR_CPSIZE(2)  /*!< 256 */
#define GMC_CPSIZE_512                        GMC_BCR_CPSIZE(3)  /*!< 512 */
#define GMC_CPSIZE_1024                       GMC_BCR_CPSIZE(4)  /*!< 1024 */
#define IS_GMC_CPSIZE(regval)                 (                                          (regval) == GMC_CPSIZE_NONE                ) ||                                           (regval) == GMC_CPSIZE_128                 ) ||                                           (regval) == GMC_CPSIZE_256                 ) ||                                           (regval) == GMC_CPSIZE_512                 ) ||                                           (regval) == GMC_CPSIZE_1024                ) ||                                    )
#define GMC_BCR_CBURSTRW_OFS                 19U  /*!< N/A */
#define GMC_BCR_CBURSTRW_MASK                BIT(19)
#define GMC_BCR_CBURSTRW(regval)             (BIT(19) & ((uint32_t)(regval) << 19))
#define GMC_CBURSTRW_ENABLE                   BIT(19)  /*!< ENABLE */
#define GMC_CBURSTRW_DISABLE                  0x0UL  /*!< DISABLE */
#define IS_GMC_CBURSTRW(regval)               (                                        (regval) == GMC_CBURSTRW_ENABLE              ) ||                                         (regval) == GMC_CBURSTRW_DISABLE             ) ||                                    )
#define GMC_BCR_CCLKEN_OFS                   20U  /*!< N/A */
#define GMC_BCR_CCLKEN_MASK                  BIT(20)
#define GMC_BCR_CCLKEN(regval)               (BIT(20) & ((uint32_t)(regval) << 20))
#define GMC_CCLKEN_ENABLE                     BIT(20)  /*!< ENABLE */
#define GMC_CCLKEN_DISABLE                    0x0UL  /*!< DISABLE */
#define IS_GMC_CCLKEN(regval)                 (                                          (regval) == GMC_CCLKEN_ENABLE              ) ||                                           (regval) == GMC_CCLKEN_DISABLE             ) ||                                    )
#define GMC_BCR_WFDIS_OFS                    21U  /*!< N/A */
#define GMC_BCR_WFDIS_MASK                   BIT(21)
#define GMC_BCR_WFDIS(regval)                (BIT(21) & ((uint32_t)(regval) << 21))
#define GMC_WFDIS_Enable                      BIT(21)  /*!< Enable */
#define GMC_WFDIS_DISABLE                    0x0UL  /*!< DISABLE */
#define IS_GMC_WFDIS(regval)                  (                                           (regval) == GMC_WFDIS_Enable              ) ||                                    )
#define GMC_BCR_BMAP_MASK                    BITS(22,23)
#define GMC_BCR_BMAP(regval)                 (BITS(22,23) & ((uint32_t)(regval) << 22))

#define GMC_BCR_EXTEND_MASK                  BITS(24,29)
#define GMC_BCR_EXTEND(regval)               (BITS(24,29) & ((uint32_t)(regval) << 24))

#define GMC_BCR_GMC_EN_OFS                   31U  /*!< N/A */
#define GMC_BCR_GMC_EN_MASK                  BIT(31)
#define GMC_BCR_GMC_EN(regval)               (BIT(31) & ((uint32_t)(regval) << 31))
#define GMC_GMC_EN_ENABLE                     BIT(31)  /*!< ENABLE */
#define GMC_GMC_EN_DISABLE                    0x0UL  /*!< DISABLE */

/* ===== BTR===== */
#define GMC_BTR_ADDSET_MASK                  BITS(0,3)
#define GMC_BTR_ADDSET(regval)               (BITS(0,3) & ((uint32_t)(regval) << 0))
#define GMC_BTR_ADDHLD_MASK                  BITS(4,7)
#define GMC_BTR_ADDHLD(regval)               (BITS(4,7) & ((uint32_t)(regval) << 4))
#define GMC_BTR_DATAST_MASK                  BITS(8,15)
#define GMC_BTR_DATAST(regval)               (BITS(8,15) & ((uint32_t)(regval) << 8))
#define GMC_BTR_BUSTURN_MASK                 BITS(16,19)
#define GMC_BTR_BUSTURN(regval)              (BITS(16,19) & ((uint32_t)(regval) << 16))
#define GMC_BTR_CLKDIV_MASK                  BITS(20,23)
#define GMC_BTR_CLKDIV(regval)               (BITS(20,23) & ((uint32_t)(regval) << 20))
#define GMC_BTR_DATLAT_MASK                  BITS(24,27)
#define GMC_BTR_DATLAT(regval)               (BITS(24,27) & ((uint32_t)(regval) << 24))
#define GMC_BTR_ACCMOD_MASK                  BITS(28,29)
#define GMC_BTR_ACCMOD(regval)               (BITS(28,29) & ((uint32_t)(regval) << 28))
#define GMC_BTR_ACCMOD_A                          GMC_BTR_ACCMOD(0)  /*!< A */
#define GMC_BTR_ACCMOD_B                          GMC_BTR_ACCMOD(1)  /*!< B */
#define GMC_BTR_ACCMOD_C                          GMC_BTR_ACCMOD(2)  /*!< C */
#define GMC_BTR_ACCMOD_D                          GMC_BTR_ACCMOD(3)  /*!< D */
#define IS_BTR_GMC_ACCMOD(regval)                 (                                          (regval) == GMC_BTR_ACCMOD_A                   ) ||                                           (regval) == GMC_BTR_ACCMOD_B                   ) ||                                           (regval) == GMC_BTR_ACCMOD_C                   ) ||                                           (regval) == GMC_BTR_ACCMOD_D                   ) ||                                    )

#define GMC_BTR_EARLYTIME_MASK                  BITS(30,31)
#define GMC_BTR_EARLYTIME(regval)               (BITS(30,31) & ((uint32_t)(regval) << 30))

 /* ===== BWTR===== */
#define GMC_BWTR_ADDSET_MASK                  BITS(0,3)
#define GMC_BWTR_ADDSET(regval)               (BITS(0,3) & ((uint32_t)(regval) << 0))
#define GMC_BWTR_ADDHLD_MASK                  BITS(4,7)
#define GMC_BWTR_ADDHLD(regval)               (BITS(4,7) & ((uint32_t)(regval) << 4))
#define GMC_BWTR_DATAST_MASK                  BITS(8,15)
#define GMC_BWTR_DATAST(regval)               (BITS(8,15) & ((uint32_t)(regval) << 8))
#define GMC_BWTR_BUSTURN_MASK                 BITS(16,19)
#define GMC_BWTR_BUSTURN(regval)              (BITS(16,19) & ((uint32_t)(regval) << 16))
#define GMC_BWTR_RESERVED_MASK                BITS(20,27)
#define GMC_BWTR_RESERVED(regval)             (BITS(20,27) & ((uint32_t)(regval) << 20))
#define GMC_BWTR_ACCMOD_MASK                  BITS(28,29)
#define GMC_BWTR_ACCMOD(regval)               (BITS(28,29) & ((uint32_t)(regval) << 28))
#define GMC_BWTR_ACCMOD_A                          GMC_BWTR_ACCMOD(0)  /*!< A */
#define GMC_BWTR_ACCMOD_B                          GMC_BWTR_ACCMOD(1)  /*!< B */
#define GMC_BWTR_ACCMOD_C                          GMC_BWTR_ACCMOD(2)  /*!< C */
#define GMC_BWTR_ACCMOD_D                          GMC_BWTR_ACCMOD(3)  /*!< D */


#define BANK_SRAM_ADDR              (GMC_SRAM1_BASE+4)

void EXMC_PCRAM_BufferWrite(uint8_t* , uint32_t , uint32_t );
void EXMC_PCRAM_BufferRead(uint8_t* , uint32_t , uint32_t );
void exmc_pcram_init(void);
void spi_pcram_init(void);
uint8_t SPI_PCRAM_ReadWriteByte(uint8_t txData);
uint8_t SPI_PCRAM_ReadByte(void);
void SPI_PCRAM_WriteByte(uint8_t txData);
void SPI_PCRAM_WriteAddr(uint32_t pcramAddr);
void SPI_PCRAM_Wip(void);
void SPI_PCRAM_WriteEnable(void);
void SPI_PCRAM_BuffWrite(uint8_t* buf, uint32_t addr, uint8_t len);
void SPI_PCRAM_BuffRead(uint8_t* buf, uint32_t addr, uint8_t len);
uint8_t pcram_sleep(uint8_t);
uint8_t pcram_wakeup(uint8_t);
void exmc_pcram_clear(uint32_t WriteAddr, uint32_t NumByteToWrite);
#endif /* GD32VF103_PCRAM_H */
